home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / obsolete / pwidget.pro < prev    next >
Text File  |  1997-07-08  |  30KB  |  951 lines

  1. ; $Id: pwidget.pro,v 1.6 1997/01/15 04:02:19 ali Exp $
  2. ;
  3. ; Copyright (c) 1993-1997, Research Systems, Inc.  All rights reserved.
  4. ;       Unauthorized reproduction prohibited.
  5.  
  6. pro list_draw, i0, i1, ERASE = erase    ;Draw the annotations from the list
  7. common pwidget_comm, pw, original, style, list
  8.  
  9. oldclip = !p.noclip
  10. !p.noclip = 1
  11.  
  12. for i=i0, i1 do begin        ;Each thing
  13.     a = list(i)
  14.     if keyword_set(erase) then c = !p.background else c = a.color
  15.     p = convert_coord(a.params(0:1), a.params(2:3), norm = a.acoord eq 1, $
  16.         data = a.acoord eq 0, /TO_NORM)
  17.     boxx = [p(0,0), p(0,1), p(0,1), p(0,0), p(0,0)]
  18.     boxy = [p(1,0), p(1,0), p(1,1), p(1,1), p(1,0)]
  19.     case a.name of 
  20.     'ARROW' : arrow, p(0,0), p(1,0), p(0,1), p(1,1), $
  21.         THICK = a.params(4), color = c, /norm, /SOLID
  22.     'BOX' : BEGIN
  23.         if a.aback then polyfill, boxx, boxy, color=!p.background, $
  24.             /NORM
  25.         plots, boxx, boxy, thick = a.params(4), color = c, /norm
  26.         ENDCASE
  27.     'TEXT' : xyouts, p(0,0), p(1,0), a.text, /NORM, $
  28.         chars = a.params(5), align = a.params(6), color = c
  29.     'LEGEND': BEGIN
  30.         x0 = min(boxx, max = x1)
  31.         y0 = min(boxy, max = y1)
  32.         if a.aback then polyfill, boxx, boxy, color=!p.background, $
  33.             /NORM
  34.         plots, boxx, boxy, thick = a.params(4), color = c, /norm
  35.         dy = (y1-y0) / (pw.n(0)+1)    ;Height
  36.         dx = (x1-x0) / 20.
  37.         for j=0, pw.n(0)-1 do begin    ;Each annotation
  38.            y =  y0 + (j+1) * dy
  39.            if keyword_set(erase) then cc = !p.background $
  40.             else cc = style(j).color           
  41.            xyouts, x0+dx, y, /NORM, style(j).name, color = cc, $
  42.             chars = a.params(5), width = s
  43.            plots, [ s + 2*dx, 19*dx]+x0, y, /NORM, $
  44.             color = cc, lines = style(j).linestyle, $
  45.             thick = style(j).thick
  46.            ENDFOR
  47.         ENDCASE
  48.     ENDCASE
  49. ENDFOR
  50. !p.noclip = oldclip
  51. END
  52.  
  53.  
  54.  
  55. pro pw_redraw        ;Redraw the entire thing
  56. common pwidget_comm, pw, original, style, list
  57.  
  58. s = style(0)
  59. if pw.n(0) eq 1 then $
  60.     plot,    routine_names(pw.vnames(0), FETCH = pw.level), $
  61.         routine_names(pw.vnames(1), FETCH = pw.level), $
  62.         color=s.color, linestyle=s.linestyle, thick=s.thick, $
  63.         psym=s.psym, symsize = s.symsize, xtype = !x.type, $
  64.         ytype = !y.type $
  65. else begin
  66.     plot,    (routine_names(pw.vnames(0), FETCH = pw.level))(*,0), $
  67.         (routine_names(pw.vnames(1), FETCH = pw.level))(*,0), $
  68.         color=s.color, linestyle=s.linestyle, thick=s.thick, $
  69.         psym=s.psym, symsize = s.symsize, xtype = !x.type, $
  70.         ytype = !y.type 
  71.     sx = pw.n(1) ne 1
  72.     sy = pw.n(2) ne 1
  73.     for i=1, pw.n(0)-1 do begin
  74.        s = style(i)
  75.        oplot, (routine_names(pw.vnames(0), FETCH = pw.level))(*,i*sx), $
  76.         (routine_names(pw.vnames(1), FETCH = pw.level))(*,i*sy), $
  77.         color=s.color, linestyle=s.linestyle, thick=s.thick, $
  78.         psym=s.psym, symsize = s.symsize 
  79.     endfor
  80. endelse
  81. list_draw, 0, pw.nlist-1        ;Add extras
  82.  
  83.    p = pw.pwidgets            ;Redraw axis text
  84.    for i=0,1 do begin
  85.     if i eq 0 then t = !x.range else t = !y.range
  86.     if t(0) eq t(1) then begin
  87.        if i eq 0 then t = !x.crange else t = !y.crange
  88.        endif
  89.     WIDGET_CONTROL, WIDGET_INFO(p(i+1),/CHILD), GET_UVALUE=x
  90.     WIDGET_CONTROL, x.range(0), SET_VALUE=strtrim(t(0),2)
  91.     WIDGET_CONTROL, x.range(1), SET_VALUE=strtrim(t(1),2)
  92.     endfor
  93.  
  94. end
  95.  
  96. pro pw_set_line, new=new, name = name    ;Set the elements of a line
  97. common pwidget_comm, pw, original, style, list
  98.  
  99. if n_elements(new) ne 0 then begin
  100.     pw.lindex = new
  101.     s = style(new)
  102.     widget_control, pw.lname, set_value=s.name
  103.     widget_control, pw.color, set_value = s.color
  104.     widget_control, pw.linestyle(s.linestyle), /SET_BUTTON
  105.     widget_control, pw.thick(s.thick), /SET_BUTTON
  106.     if s.psym ge 0 then j = s.psym else j = 8-s.psym
  107.     widget_control, pw.psym(j), /SET_BUTTON
  108.     endif
  109. if n_elements(name) ne 0 then begin
  110.     style(pw.lindex).name = name
  111.     widget_control, pw.lbutton(pw.lindex), set_value=name
  112.     endif
  113. end
  114.  
  115.  
  116. function row_buttons, base, label, choices, uvalues, EXCLUSIVE = exclusive, $
  117.      NONEXCLUSIVE = nonexclusive, SET_BUTTON = set_index, NO_RELEASE = no_rel
  118. ; Make a row base with buttons.
  119. ; Default no_rel = 1.
  120. a = widget_base(base, /row)
  121. if strlen(label) gt 0 then b = widget_label(a, value= label)
  122. b = widget_base(a, /row, exclusive = keyword_set(exclusive), $
  123.     nonexclu = keyword_set(nonexclusive))
  124. rslt = lonarr(n_elements(choices))
  125. if n_elements(uvalues) le 0 then uvalues = choices
  126. nuv1 = n_elements(uvalues)-1
  127. if n_elements(no_rel) le 0 then no_rel = 1
  128. for i=0,n_elements(choices)-1 do  $
  129.   rslt(i) = widget_button(b, value=choices(i), $
  130.     uvalue = uvalues(i < nuv1), $
  131.     NO_REL = keyword_set(no_rel))
  132. if n_elements(set_index) gt 0 then widget_control, rslt(set_index), /set_button
  133. return, rslt
  134. end
  135.  
  136.  
  137.  
  138. function CW_AXIS_WIDGETG, id        ;Get the value of an axis widget
  139. widget_control, widget_info(id, /child), get_uvalue=state
  140. return, state
  141. end
  142.  
  143.  
  144. function CW_AXIS_WIDGET, parent, LABEL = label, FRAME = frame, $
  145.     UVALUE = uvalue, name = name
  146. if n_elements(frame) eq 0 then frame = 0
  147. if n_elements(uvalue) eq 0 then uvalue = 0
  148. if n_elements(label) eq 0 then label = ''
  149.  
  150. base = widget_base(parent, /COLUMN, FRAME = frame, $
  151.     EVENT_FUNC = 'CW_AXIS_WIDGETE', FUNC_GET_VALUE = 'CW_AXIS_WIDGETG', $
  152.     PRO_SET_VALUE = 'CW_AXIS_WIDGETS', UVALUE = uvalue)
  153. state = { CW_AXIS_STATE, name : '', $
  154.     type : lonarr(2),  title : 0L, style : lonarr(4), range : lonarr(2), $
  155.     margin : lonarr(2), tmodes : lonarr(3), tbase: lonarr(3), $
  156.     fixed:lonarr(3), ftick: fltarr(3) }
  157.  
  158. state.name = name
  159. child = widget_label(base, value = label, xsize=75)
  160. state.type = row_buttons(base, 'Scaling:', ['Linear', 'Logarithmic'], $
  161.     '@C'+name + ['.type=0', '.type=1'], /exclu, set_button = uvalue.type)
  162. state.style = row_buttons(base, 'Style:', $
  163.     ['Exact', 'Extend', 'Suppress', 'No Box'], $
  164.     ['style1','style2','style4','style8'], /NONEXC, NO_REL = 0)
  165. for i=0,3 do if (uvalue.style and 2^i) ne 0 then $
  166.     widget_control, state.style(i), /set_button
  167. junk = widget_base(base, /row)
  168. junk1 = widget_label(junk, value = 'Title:', xsize=75)
  169. state.title = widget_text(junk, xsize = 24, ysize = 1, /edit, $
  170.     uvalue="@S"+name+".TITLE=", value=uvalue.title, /FRAME)
  171.  
  172. junk = widget_base(base, /row)
  173. junk1 = widget_label(junk, value = 'Range: ', xsize=75)
  174. state.range = [ $
  175.     widget_text(junk, xsize=12, ysize=1, /edit, $
  176.         uvalue= "@Nwidget_control, s.range(1), /INPUT_FOCUS & " + $
  177.         name+'.range(0)=',/FRAME, $
  178.         value=strtrim(uvalue.range(0),2)), $
  179.     widget_text(junk, xsize=12, ysize=1, /edit, $
  180.         uvalue= "@Nwidget_control,s.range(0), /INPUT_FOCUS & " + $
  181.         name+'.range(1)=', /FRAME, $
  182.         value=strtrim(uvalue.range(1),2))]
  183.  
  184. junk = widget_base(base, /row)
  185. junk1 = widget_label(junk, value = 'Margins: ', xsize=75)
  186. state.margin = [ $
  187.     widget_text(junk, xsize=12, ysize=1, /edit, $
  188.     uvalue= "@N"+name+'.margin(0)=', /FRAME, $
  189.         value = strtrim(uvalue.margin(0),2)), $
  190.     widget_text(junk, xsize=12, ysize=1, /edit, $
  191.     uvalue= "@N"+name+'.margin(1)=', /FRAME, $
  192.         value = strtrim(uvalue.margin(1),2))]
  193.  
  194. base1 = widget_base(base, /column, /frame)
  195. junk1 = widget_label(base1, value = 'Ticks')
  196.  
  197. state.tmodes = row_buttons(base1, 'Values:',  $
  198.     ['Auto','Fixed Increment'], /EXCLUSIVE, SET=0)
  199. if uvalue.tickv(0) eq uvalue.tickv(1) then i = 0 else i = 2  ;Button to select?
  200. widget_control, state.tmodes(i), /SET_BUTTON
  201.  
  202. state.tbase(0) = (junk = widget_base(base1, /ROW))
  203. for i=0,2 do begin
  204.     junk1 = widget_label(junk, value=(['From:', 'To:', 'Incr:'])(i))
  205.     if i eq 2 then begin
  206.       x = uvalue.range(1) - uvalue.range(0)
  207.       if x eq 0. then x = 1 else x = x/5
  208.     endif else x = uvalue.range(i)
  209.     state.ftick(i) = x
  210.     state.fixed(i) = widget_text(junk, xsize=9, ysize = 1, /edit, $
  211.         uvalue='F0', /FRAME, value=strtrim(x,2))
  212.     ENDFOR
  213.  
  214. state.tbase(1) = (junk = widget_base(base1, /COLUMN))
  215. for j=0,1 do if (j+1) ne i then widget_control, state.tbase(j), map=0
  216. widget_control, child, set_uvalue = state
  217. return, base
  218. end
  219.  
  220.  
  221. function get_numeric_widget, str, id, FLOAT=flt, $     ;Get a numeric value
  222.     MINV = minv, MAXV = maxv
  223. on_ioerror, bad
  224. msg = "Non-numeric value entered"
  225. again: str = strtrim(str,2)
  226. if keyword_set(flt) then f = float(str) else f = long(str)
  227. if n_elements(minv) gt 0 then if f lt minv then begin
  228.     msg = "Value is below minimum of "+strtrim(minv,2)
  229.     goto, bad
  230.     endif
  231. if n_elements(maxv) gt 0 then if f gt maxv then begin
  232.     msg = "Value is above maximum of "+strtrim(maxv,2)
  233.     goto, bad
  234.     endif
  235.     
  236. return, f
  237. bad:    a= widget_base(/column, TITLE="ERROR")
  238.     b = widget_label(a, value = msg)
  239.     b = widget_label(a, value = "Enter the correct value: ")
  240.     widget_control, a, /real
  241.     junk = widget_event(id)
  242.     widget_control, id, get_value=str
  243.     str = str(0)
  244.     widget_control, id, set_value = str
  245.     widget_control, a, /destroy
  246.     goto, again    
  247. end
  248.  
  249.  
  250. pro pw_set, id, uval, s     ;Set a variable or execute a command
  251. common pwidget_comm, pw, original, style, list
  252.  
  253.  
  254. i = pw.lindex
  255. case strmid(uval,1,1) of
  256. 'N':    BEGIN        ;Read numeric value from text widget
  257.     widget_control, id, get_value = value
  258.     a = get_numeric_widget(value(0), id, /FLOAT)
  259.     k = execute(strmid(uval, 2, 100) + 'a')
  260.     ENDCASE
  261. 'S':    BEGIN        ;Read string value from text widget
  262.     widget_control, id, get_value = value
  263.     value = strtrim(value(0),2)
  264.     k = execute(strmid(uval, 2,100) + 'value')
  265.     ENDCASE
  266. 'C':    BEGIN        ;Execute uvalue
  267.     k = execute(strmid(uval, 2,100))
  268.     ENDCASE
  269. ENDCASE
  270. end
  271.  
  272. function CW_AXIS_WIDGETE, ev
  273. base = ev.handler
  274. id = ev.id
  275. widget_control, (c  = widget_info(base, /child)), get_uvalue = state
  276. widget_control, id, get_uvalue = uval
  277.  
  278. ;print, uval
  279.  
  280. if strmid(uval,0,1) eq '@' then pw_set, id, uval, state $
  281. ELSE if strpos(uval, 'style') eq 0 then begin
  282.       j = strmid(uval,5,1)        ;Bit value
  283.       if ev.select ne 0 then op = ' or ' else op = ' and  not '
  284.       k = state.name + '.style =' + state.name + ".style" + op + j
  285.       k = execute(k)
  286. ENDIF   ELSE case uval of
  287. "Auto": BEGIN
  288.     for i=0,1 do widget_control, state.tbase(i), map = 0
  289.     k = execute(state.name + '.tickv = 0. & ' + state.name + '.ticks=0')
  290.     ENDCASE
  291. "F0":    BEGIN        ;Fixed increment widget
  292.     i = (where(id eq state.fixed))(0)    ;Index number
  293.     widget_control, id, get_value = value
  294.     state.ftick(i) = get_numeric_widget(value(0), id, /FLOAT)
  295.     widget_control, c, set_uvalue = state    ;Save value
  296.     widget_control, state.fixed((i+1) mod 3), /INPUT_FOCUS
  297.     goto, do_fixed
  298.     ENDCASE
  299. "Fixed Increment": BEGIN
  300.     for i=0,1 do widget_control, state.tbase(i), map=1-i
  301. do_fixed:
  302.     a = state.ftick
  303.     if a(2) le 0.0 then return, 0
  304.     n = long((a(1)-a(0))/a(2)+.001)        ;# of ticks
  305.     if (n lt 1) or (n gt 29) then return,0
  306.     b = findgen(n+1)*a(2) + a(0)
  307.     k = execute(state.name + '.TICKV = b & ' + state.name + '.TICKS = n')
  308.     k = execute(state.name + '.RANGE = a(0:1)')
  309.     ENDCASE
  310. else : print,'No match'    
  311. endcase
  312. pw_redraw
  313. return, 0
  314. end
  315.  
  316.  
  317.  
  318. function CW_COLOR_INDEX, parent, LABEL = label, FRAME = frame, $
  319.     UVALUE = uvalue, XSIZE = xsize, YSIZE = ysize, NCOLORS = ncolors, $
  320.     START_COLOR = start_color
  321.  
  322. if n_elements(frame) eq 0 then frame = 0
  323. if n_elements(uvalue) eq 0 then uvalue = 0
  324. if n_elements(xsize) eq 0 then xsize = 256
  325. if n_elements(ysize) eq 0 then ysize = 12
  326. if n_elements(ncolors) eq 0 then ncolors = !d.N_COLORS
  327. if n_elements(start_color) eq 0 then start_color = 0
  328. if n_elements(label) eq 0 then label = ''
  329.  
  330. base = widget_base(parent, /ROW, FRAME = frame, $
  331.     EVENT_FUNC = 'CW_COLOR_INDEXE', FUNC_GET_VALUE = 'CW_COLOR_INDEXG', $
  332.     PRO_SET_VALUE = 'CW_COLOR_INDEXS', UVALUE = uvalue)
  333. state = { CW_C_INDEX_STATE, $
  334.     txt_id : 0L, rect_id : 0L, pwin_id : 0L, inited : 0, efun:'', $
  335.     scale : float(ncolors) / xsize, value : 0L, $
  336.     start_color : start_color , extra:0L}  ;agrees with cw_color_index.pro
  337.                            ;struct def. -KDB 12/93
  338. child = widget_label(base, value = label)
  339. state.txt_id = widget_text(base, xsize=5, ysize = 1, value = '(0)')
  340. state.rect_id = widget_draw(base, /frame, xsize = 16, ysize = ysize, $
  341.     uvalue = 0)
  342. state.pwin_id = widget_draw(base, /frame, xsize = xsize, $
  343.         ysize = ysize, /BUTTON)
  344. widget_control, child, set_uvalue = state
  345. return, base
  346. end
  347.  
  348.  
  349. function CW_COLOR_INDEXG, id
  350.     widget_control, widget_info(id, /child), get_uvalue = state
  351.     return, state.value
  352. end
  353.  
  354. pro CW_COLOR_INDEXS, id, value        ;Set color index widget value
  355. widget_control, (draw = widget_info(id, /child)), get_uvalue = state
  356. old_win = !d.window
  357.  
  358. if state.inited eq 0 then begin
  359.     widget_control, state.pwin_id, get_value = i
  360.     wset, i
  361.     tv, state.scale * indgen(!d.x_size) # replicate(1, !d.y_size) + $
  362.         state.start_color
  363.     state.inited = 1
  364.     endif
  365. state.value = value            ;Save new value
  366. widget_control, draw, set_uvalue = state
  367. widget_control, state.rect_id, get_value = i
  368. wset, i
  369. tv, replicate(value, !d.x_size, !d.y_size)
  370. wset, old_win
  371. widget_control, state.txt_id, set_value = '(' + strtrim(value,2) + ')'
  372. return
  373. end
  374.  
  375.  
  376. function CW_COLOR_INDEXE, ev        ;Color index widget's event proc
  377. if ev.press ne 0 then return, 0
  378. base = ev.handler
  379. widget_control, widget_info(base, /child), get_uvalue = state
  380. c = long(state.start_color + (ev.x * state.scale))  ;New color
  381. CW_COLOR_INDEXS, base, c    
  382. return, { CW_COLOR_INDEX, ID: base, TOP: ev.top, HANDLER: 0L, VALUE: c}
  383. end
  384.  
  385.  
  386.  
  387. function b_button, a    ;Return a 1 bit deep bitmap given a byte image.
  388.             ;width of image MUST be a multiple of 8.
  389. s = size(a)
  390. b = bytarr(s(1)/8, s(2))
  391. if (s(1) and 7) ne 0 then $
  392.     message, 'B_BUTTON: image width must be a multiple of 8.'
  393. subs = lindgen(n_elements(b)) * 8
  394. for ibit = 0,7 do b = b or byte(2^ibit) * (a(subs+ibit) ne 0b)
  395. return, reverse(b,2)
  396. end
  397.  
  398.             ;Make charsize buttons
  399. function charsize_but, base, width, e_string, SET_INDEX = set
  400. b = widget_base(base, /row)    ;CHARSIZE
  401. junk = widget_label(b, value='Char Size:', xsize=70)
  402. b = widget_base(b, /row, /exclusive)
  403. ct = [.75, 1, 1.5, 2., 3.]
  404. n = n_elements(ct)
  405. window, /free, /pixmap, xsize = width, ysize=16
  406. buttons = lonarr(n)
  407. if n_elements(set) eq 0 then set = -1
  408. for i=0,n-1 do begin
  409.     erase, 0
  410.     xyouts, width/2, 0, /dev, ali=0.5, 'Abc', CHARS = ct(i), $
  411.         col=!d.n_colors-1
  412.     buttons(i) = widget_button(b, value = b_button(tvrd()), $
  413.             uvalue = e_string+strtrim(ct(i),2), /NO_REL)
  414.     if (ct(i) eq !p.charsize) or (i eq set) then $
  415.         widget_control, buttons(i), /SET_BUTTON
  416.     endfor
  417. wdelete
  418. return, buttons
  419. end
  420.  
  421.  
  422.  
  423.  
  424. pro zoom_drag, release, x, y        ;Zoom or drag main window
  425. ;    Release = button that was released.
  426. common pwidget_comm, pw, original, style, list
  427.  
  428.  
  429. redraw = 0
  430. if release eq 2 then begin   ;Done zooming?
  431.   pw.r_prev = [ !x.range, !y.range]
  432.   p0 = convert_coord([pw.boxx(0), pw.boxy(0)], /TO_DATA, /DEV)
  433.   p1 = convert_coord([pw.boxx(2), pw.boxy(2)], /TO_DATA, /DEV)
  434.   if pw.xmx(0) lt pw.xmx(1) then $
  435.     !x.range = [p0(0) < p1(0), p0(0) > p1(0)] $
  436.   else !x.range = [p0(0) > p1(0), p0(0) < p1(0)]
  437.   if pw.ymx(0) lt pw.ymx(1) then $
  438.     !y.range = [p0(1)< p1(1), p0(1)> p1(1)] $
  439.   else !y.range = [p0(1) > p1(1), p0(1) < p1(1)]
  440.   redraw = 1
  441. endif        ;middle
  442. if release eq 1 then begin    ;Drag
  443.   pw.r_prev = [ !x.range, !y.range ]
  444.   dx = (pw.boxx(0) - x)/!x.s(1)/!d.x_size
  445.   dy = (pw.boxy(0) - y)/!y.s(1)/!d.y_size
  446.   !x.range = !x.range + dx
  447.   !y.range = !y.range + dy
  448.   redraw = 1
  449. endif
  450.  
  451. if redraw then begin    ;Update text windows
  452.    pw_redraw
  453.    endif
  454. end
  455.  
  456.  
  457. pro pwidget_events, ev
  458. common pwidget_comm, pw, original, style, list
  459.  
  460.  
  461. id = ev.id
  462.  
  463. wset, pw.window
  464. if id eq pw.draw then BEGIN        ;Mouse or motion?
  465.         ; Box is true for drawing a box. Box or line mode?
  466.     if pw.mode eq 4 then box = (pw.amode eq 1) or (pw.amode eq 3)  $
  467.     else box = (pw.button or ev.press) eq 2
  468.  
  469.     if (ev.press eq 0) and (ev.release eq 0) then begin ;No button chg?
  470.         p = convert_coord([ev.x, ev.y], /TO_DATA, /DEV)
  471.         WIDGET_CONTROL, pw.txt, set_value= 'X,Y = ' + $
  472.             strtrim(p(0),2) + ', ' + strtrim(p(1),2)
  473.     endif
  474.  
  475.     if pw.button ne 0 then begin    ;Dragging?
  476.         device, set_graphics=6    ;XOR writing mode
  477.         if !d.name eq 'X' then device, /bypass
  478.             ;True if a single point
  479.         point = pw.boxx(0) eq pw.boxx(1) and pw.boxy(1) eq pw.boxy(2)
  480.         if not point then begin
  481.            if box then plots,pw.boxx, pw.boxy, /dev, $;Erase old
  482.             thick=1, lines=0, color=pw.xor_color $
  483.            else plots, pw.boxx(0:1), pw.boxy(1:2), /dev, $;Erase old
  484.             thick=1, lines=0, color=pw.xor_color
  485.         endif
  486.         pw.boxx([1,2]) = ev.x
  487.         pw.boxy([2,3]) = ev.y
  488.         if ev.release eq 0 then begin    ;Draw again?
  489.           if box then plots,pw.boxx, pw.boxy, /dev, $ ;Draw new
  490.             thick=1, lines=0, color=pw.xor_color $
  491.           else plots, pw.boxx(0:1), pw.boxy(1:2), /dev, $ ;Draw new
  492.                 thick=1, lines=0, color=pw.xor_color
  493.         endif                ;Release
  494.         device, set_graphics=3
  495.         if !d.name eq 'X' then device, bypass=0
  496.     endif            ;Dragging
  497.  
  498.     if ev.press ne 0 then begin    ;Button down?
  499.         pw.button = pw.button or ev.press
  500.         pw.boxx = replicate(ev.x,5)
  501.         pw.boxy = replicate(ev.y,5)
  502.     endif                ;Press
  503.  
  504.     if ev.release ne 0 then begin    ;Done with motion?
  505.         pw.button = pw.button and (not ev.release)
  506.         if pw.mode ne 3 then zoom_drag, ev.release, ev.x, ev.y $
  507.         else begin        ;Annotation...
  508.           if pw.nlist ge n_elements(list)-1 then begin
  509.             print,'List Full'
  510.             return
  511.             endif
  512.           names = ['ARROW', 'BOX', 'TEXT', 'LEGEND']
  513.           p = convert_coord(pw.boxx(0:1), pw.boxy([0,2]), /device, $
  514.             to_normal = pw.acoord eq 1, to_data = pw.acoord eq 0)
  515.           widget_control,  pw.atext, get_value = s
  516.           list(pw.nlist) =  { PW_LIST, names(pw.amode), s(0), $
  517.             pw.acolor, pw.acoord, pw.aback, $
  518.             [p(0,0), p(0,1), p(1,0), p(1,1), $
  519.                 pw.athick, pw.atextsize, pw.atextal]}
  520.           list_draw, pw.nlist, pw.nlist
  521.           pw.nlist = pw.nlist + 1
  522.           endelse            ;Annotation
  523.     endif            ;Release
  524.  
  525.     return
  526. ENDIF            ;Button / motion event
  527.  
  528. redraw = 0        ;True to redraw
  529. WIDGET_CONTROL, id, get_uvalue = uval
  530.  
  531. ;print, uval
  532. if strmid(uval, 0,1) eq '@' then begin
  533.     pw_set, id, uval, pw
  534.     redraw = 1
  535. ENDIF ELSE if strmid(uval, 0,1) eq '#' then begin
  536.     pw_set, id, uval, pw
  537. ENDIF ELSE if strmid(uval, 0, 6) eq 'PRINT_' then begin    ;Print
  538.     name = strmid(uval, 6,100)
  539.     a = widget_base(TITLE = 'Working:')
  540.     b = widget_label(a, value = 'Creating a Plot file for: ' + name) 
  541.     widget_control, a, /realize
  542.     olddev    = !D.NAME
  543.     t0 = systime(1)
  544.     if name eq 'EPS' then begin
  545.         set_plot, 'PS'
  546.         device, encap = 1
  547.     endif else set_plot, name, /COPY
  548.     pw_redraw
  549. ;;;;    device, /close
  550.     set_plot, olddev, /COPY
  551.     t0 = 3 - (systime(1) - t0)    ;Show message for 3 secs
  552.     if t0 gt 0 then wait, t0
  553.     widget_control, a, /destroy
  554. ENDIF ELSE CASE uval of
  555. "EXIT":   widget_control, ev.top, /destroy
  556. "UNDO": if pw.nlist gt 0 then begin
  557.         pw.nlist = pw.nlist -1
  558.         list_draw, pw.nlist, pw.nlist, /ERASE
  559.         endif
  560. "MODE": BEGIN
  561.     i = (where(id eq pw.mode_buttons))(0)
  562.     if i eq pw.mode then return
  563.     widget_control, pw.pwidgets(pw.mode), map = 0
  564.     pw.mode = i
  565.     widget_control, pw.pwidgets(pw.mode), map = 1
  566.     redraw = 0
  567.     ENDCASE
  568. "RESET_SCL": BEGIN
  569.     !x.range = pw.xmx
  570.     !y.range = pw.ymx
  571.     !x.type = 0
  572.     !y.type = 0
  573.     redraw = 1
  574.     ENDCASE
  575. "RESET_ANN": BEGIN
  576.     pw.nlist = 0
  577.     redraw = 1
  578.     ENDCASE
  579. "RESET_REDRAW": redraw = 1
  580. "RESET_ALL": BEGIN
  581.     !x = original.x
  582.     !y = original.y
  583.     !p = original.p
  584.     pw.nlist = 0
  585.     redraw = 1
  586.     ENDCASE
  587. "COLOR":  tek_color
  588. "BW":    BEGIN
  589.     c = bytscl([0, 15-indgen(15)])
  590.     tvlct,c,c,c
  591.     ENDCASE
  592.     "HELP": BEGIN
  593. ;    xdisplayfile, 'pwidget.txt', $    ;Debugging
  594.     xdisplayfile, filepath("pwidget.txt", subdir=['help', 'widget']), $  ;Working
  595.         title = "Pwidget Help", $
  596.         group = ev.top, $
  597.         width = 72, height = 24
  598.     ENDCASE
  599. "HIDE": BEGIN
  600.     widget_control, pw.main, map=0
  601.     window, xs= !d.x_size, ys=!d.y_size, /free, title=!p.title
  602.     pw_redraw
  603.     a = widget_base(title='PWIDGET')
  604.     b = widget_button(a, value = 'Click to Resume')
  605.     widget_control, a, /real
  606.     b = widget_event(a)
  607.     widget_control, a, /destroy
  608.     wdelete, !d.window
  609.     widget_control, pw.main, map=1
  610.     ENDCASE    
  611. else:    BEGIN
  612.     print,'No match'
  613.     ENDCASE
  614. endcase
  615. if redraw then pw_redraw
  616. end
  617.  
  618.  
  619.  
  620. PRO PWIDGET, GROUP = group, x, y, SAVE = save, WINDOW_SIZE = w_size, $
  621.     RESTORE = restore
  622. ;+NODOCUMENT
  623. ;-
  624. common pwidget_comm, pw, original, style, list
  625.  
  626. if XRegistered("pwidget") THEN RETURN
  627. if n_elements(w_size) lt 2 then begin    ;Use default window size?
  628.     device, get_screen = w_size
  629.     w_size = (w_size(0) * [5, 4]) / 9
  630.     endif
  631.  
  632. original = { PW_SAVE, x: !X, y: !Y, p: !P}
  633.  
  634. maxv = 8            ;Maximum # of independent vects
  635.  
  636. pw = { PW_STRUCTURE, $
  637.     main : 0L, $            ;Main base
  638.     level : 0, $            ;Routine level
  639.     n  : [0,0,0], $            ;# of vectors x,y, total
  640.     lindex : 0, $            ;Current line index
  641.     vnames : strarr(2), $        ;Names of xy vars
  642.     mode : 0, $            ;Main mode
  643.     amode : 0, $            ;Annotation mode
  644.     mode_buttons : lonarr(5), $    ;mode buttons
  645.     pwidgets : lonarr(5), $        ;Main bases
  646.     background:0L, $        ;background widget
  647.     charsize:lonarr(5), $        ;charsize widget
  648.     color:0L, $            ;color widget
  649.     draw:0L, $            ;Draw widget
  650.     window: 0, $            ;Window index
  651.     linestyle: lonarr(6), $        ;Linestyle buttons
  652.     subtitle: 0L, $            ;subtitle widget
  653.     title: 0L, $            ;title widget
  654.     psym : lonarr(16), $        ;psym buttons
  655.     thick: lonarr(7), $        ;thick buttons
  656.     ticklen : lonarr(3), $        ;ticklen buttons
  657.     lname : 0L, $            ;Line name widget
  658.     lbutton : lonarr(10), $        ;Line name buttons
  659.     msize : lonarr(4), $        ;Psymsize buttons
  660.     atext : 0L, $            ;Annotation text widget
  661.     atextsize : 1.0, $        ;Annotation text size
  662.     atextal : 0.0, $        ;Annotation text alignment
  663.     athick : 1.0, $            ;Line thickness
  664.     acolor : 1, $            ;Line color
  665.     acoord : 0, $            ;0 = data coords, 1 = norm
  666.     aback : 0, $            ;=1 to erase box background    
  667.     nlist : 0, $            ;# of items in list
  668.     xmx:fltarr(2), $
  669.     ymx: fltarr(2), $
  670.     txt : 0L, $
  671.     button : 0, $
  672.     xor_color : 0, $
  673.     boxx : fltarr(5), boxy: fltarr(5), r_prev : fltarr(4) }
  674.  
  675. col = 1            ;Default color = white = 1
  676.  
  677. style = replicate({ PW_STYLE_STRUCT, $    ;Attributes for each line
  678.         color : col, $
  679.         linestyle : !p.linestyle, $
  680.         thick : !p.thick, $
  681.         psym  : !p.psym, $
  682.         symsize : !p.symsize, $
  683.         name : ''}, maxv)
  684.  
  685. style.name = 'LINE '+    strtrim(sindgen(maxv),2)
  686.  
  687. ; Params(0:1) = x0, x1
  688. ; Params(2:3) = y0, y1
  689. list = { PW_LIST, name: '', text: '', color: 0L, acoord: 0, aback:0, $
  690.     params : fltarr(7)}
  691. list = replicate(list,30)
  692.  
  693. sx = size(x)
  694. if sx(0) eq 2 then nx = sx(2) else nx = 1
  695. pw.xmx = [min(x, max=x1), x1]    ;Get range
  696.  
  697. if n_elements(y) gt 0 then begin
  698.     sy = size(y)
  699.     if sy(0) eq 2 then ny = sy(2) else ny = 1
  700.     if nx eq 1 then n = ny else if ny eq 1 then n = nx else n = nx < ny
  701.     pw.ymx = [min(y, max=x1), x1]
  702.     pw.n = [n, nx, ny]
  703.     pw.vnames = ['X','Y']
  704. endif else begin
  705.     pw.ymx = pw.xmx
  706.     pw.xmx = [0, sx(1)-1]
  707.     pw.vnames = ['XX','X']
  708.     pw.n = [nx,1,nx]
  709.     xx = findgen(sx(1))
  710. endelse
  711.  
  712. !x.range = pw.xmx            ;Current ranges
  713. !y.range = pw.ymx
  714.  
  715.  
  716.  
  717.  
  718. if n_elements(restore) gt 0 then begin
  719.     !x = restore.x
  720.     !y = restore.y
  721.     !p = restore.p
  722.     list = restore.list
  723.     style = restore.style
  724.     pw = restore.pw
  725.     endif
  726. pw.level = ROUTINE_NAMES(/LEVEL)
  727.  
  728.  
  729. pw.mode = 0
  730.  
  731.  
  732. base_names = [ 'General', 'X Axis', 'Y Axis', 'Annotation']
  733. pw.main = widget_base(title='Pwidget',/ROW)
  734. mainl = widget_base(pw.main, /COLUMN)        ;Left side
  735. pw.draw = widget_draw(pw.main, XSIZE = w_size(0), YSIZE = w_size(1), $
  736.     RETAIN=2, /BUTTON_EVENTS, /MOTION_EVENTS)
  737.  
  738. XPdMenu, [    '" Done "            EXIT', $
  739.         '" Reset " {' , $
  740.         '" All "        RESET_ALL',$
  741.         '" Annotation "        RESET_ANN',$
  742.         '" Redraw "        RESET_REDRAW', $
  743.         '" Scaling "        RESET_SCL',$
  744.         '}', $
  745.         '" Help "            HELP', $
  746.         '" Print " {', $
  747.         '" PostScript "        PRINT_PS',$
  748.         '" Encapsulated PostScript "        PRINT_EPS',$
  749.         '" HPGL "        PRINT_HP',$
  750.         '" Dec LJ-250 "        PRINT_LJ',$
  751.         '" HP PCL "        PRINT_PCL',$
  752.         '" CGM "        PRINT_CGM',$
  753.         '}', $
  754.         '"Hide Controls"    HIDE' $
  755.     ],  mainl
  756.  
  757. pw.mode_buttons = row_buttons(mainl, '', base_names, "MODE", /EXCLU, /NO_REL)
  758. junk1 = row_buttons(mainl, '', ["Color", "Black & White"], /EXCLU, $
  759.     ["COLOR", "BW"], SET_BUTTON = 0)
  760.  
  761. cbase = widget_base(mainl)        ;Will contain multi-modes
  762.  
  763. pw.pwidgets(0) = (a = widget_base(cbase, /column))    ;General widget
  764.  
  765. a = widget_base(a, /column, /frame)    ;Top box
  766. b = widget_base(a, /row)
  767. junk = widget_label(b, value='Title:', xsize=75)
  768. pw.title = widget_text(b, xsize=32, ysize=1, value=!p.title, $
  769.     /EDIT, /FRAME, $
  770.     uvalue = '@SWidget_control, s.subtitle, /INPUT_FOCUS & !P.TITLE=')
  771. b = widget_base(a, /row)
  772. junk = widget_label(b, value='Sub-title:', xsize=75)
  773. pw.subtitle = widget_text(b, xsize=32, ysize=1, value=!p.subtitle, $
  774.     /EDIT, /FRAME, $
  775.     uvalue = '@SWidget_control, s.title, /INPUT_FOCUS & !P.SUBTITLE=')
  776.  
  777. b = widget_base(a,/row)
  778. junk = widget_label(b, value='Nsum:', xsize = 75)
  779. junk1 = widget_text(b, xsize=4, ysize=1, value=strtrim(!p.nsum,2), $
  780.     /EDIT, /FRAME, uvalue = '@N!P.NSUM=')
  781.  
  782. pw.ticklen = row_buttons(b, "Tick Style:", ['In', 'Out', 'Grid'], $
  783.     "@C!P.TICKLEN="+ ['0.02', '-0.02', '1.0'], /EXCLU)
  784. if !p.ticklen lt 0.0 then i = 1 else if !p.ticklen gt .5 then i = 2 else i = 0
  785. widget_control, pw.ticklen(i), /set_button
  786.  
  787. pw.background = CW_COLOR_INDEX(a, label = 'Bkgd ', $
  788.     uvalue = '@N!P.BACKGROUND=', NCOLORS = 16)
  789.  
  790. tek_color
  791. width = 32
  792.  
  793.  
  794. pw.charsize = charsize_but(a, width, '@C!P.CHARSIZE=', SET=1)
  795.  
  796.  
  797. window, /free, /pixmap, xsize = width, ysize=16
  798.  
  799. a = widget_base(pw.pwidgets(0), /frame, /column)
  800. n = pw.n(0)        ;Extra plots
  801. if n gt 1 then pw.lbutton = $
  802.     row_buttons(a, 'Line Select:', style(0:n-1).name, $
  803.         '#Cpw_set_line, NEW='+strtrim(indgen(n),2), /NO_REL, $
  804.         SET = 0, /EXCLUSIVE)
  805.  
  806. junk = widget_base(a,/row)
  807. junk1 = widget_label(junk ,value = 'Name:', xsize=70)
  808. pw.lname = widget_text(junk, xsize=12, ysize=1, value=style(0).name, $
  809.     uvalue = '@Spw_set_line, NAME=', /EDIT, /FRAME)
  810.  
  811. pw.color = CW_COLOR_INDEX(a, label = 'Color', NCOLORS = 16, $
  812.     uvalue = '@Nstyle(i).color=')
  813.  
  814. b = widget_base(a, /row)    ;LINESTYLES
  815. junk = widget_label(b, value='Linestyle:',xsize=70)
  816. b = widget_base(b, /row, /exclusive)
  817. for i=0,5 do begin
  818.     erase, 0
  819.     plots, [0,width-1], [8,8], /dev, lines = i, thick=1, col=col
  820.     pw.linestyle(i) = widget_button(b, value = b_button(tvrd()), $
  821.         uvalue = '@Cstyle(i).linestyle='+strtrim(i,2), /NO_REL)
  822.     if i eq !p.linestyle then widget_control, pw.linestyle(i), /SET_BUTTON
  823.     endfor
  824.  
  825.  
  826. b = widget_base(a, /row)    ;THICKNESS
  827. junk = widget_label(b, value='Thickness:', xsize=70)
  828. b = widget_base(b, /row, /exclusive)
  829. for i=1,6 do begin
  830.     erase, 0
  831.     plots, [0,width-1], [8,8], /dev, thick = i, lines=0, col=col
  832.     pw.thick(i) = widget_button(b, value = b_button(tvrd()), $
  833.             uvalue = '@Cstyle(i).thick='+strtrim(i,2), /NO_REL)
  834.     if abs(i - !p.thick) lt .5 then widget_control, pw.thick(i), $
  835.             /SET_BUTTON
  836.     endfor
  837. pw.thick(0) = pw.thick(1)
  838.  
  839. width = 24
  840. b = widget_base(a, /row)    ;PSYM
  841. junk = widget_label(b, value='Marker:', xsize=70)
  842. b = widget_base(b, column = 8, /exclusive)
  843. wdelete
  844. window, /free, /pixmap, xsize = width, ysize=16
  845. for j=-1,1,2 do for i=0,7 do begin
  846.     erase,0
  847.     plots, [width/4, 3*width/4], [8,8], /dev, psym=i * j, thick=1, $
  848.         lines=0, col=col
  849.     k = (j+1)*4+i
  850.     pw.psym(k) = widget_button(b, value = b_button(tvrd()), $
  851.             uvalue = '@Cstyle(i).psym='+strtrim(i*j,2), /NO_REL)
  852.     if (i*j) eq !p.psym then widget_control, pw.psym(k), /SET_BUTTON
  853.     endfor
  854.  
  855. width = 32
  856. b = widget_base(a, /row)    ;Marker size
  857. junk = widget_label(b, value='Marker Size:', xsize=70)
  858. b = widget_base(b, /ROW, /exclusive)
  859. wdelete
  860. window, /free, /pixmap, xsize = width, ysize=16
  861. sym_sizes = [ .5, 1., 1.5, 2.0 ]
  862. for i=0,3 do begin
  863.     erase,0
  864.     plots, [width/4, 3*width/4], [8,8], /dev, psym=-4, thick=1, $
  865.         lines=0, col=col, symsize=sym_sizes(i)
  866.     pw.msize(i) = widget_button(b, value = b_button(tvrd()), $
  867.            uvalue = '@Cstyle(i).symsize='+strtrim(sym_sizes(i),2), $
  868.            /NO_REL)
  869.     endfor
  870.  
  871. wdelete
  872.  
  873.  
  874. pw.pwidgets(1) = cw_axis_widget(cbase, /frame, label = "X Axis", uvalue = !X, $
  875.     name = '!X')
  876. pw.pwidgets(2) = cw_axis_widget(cbase, /frame, label = "Y Axis", uvalue = !Y, $
  877.     name = '!Y')
  878. ; pw.pwidgets(3) = cw_axis_widget(cbase, /frame, label = "Z Axis", $
  879. ;    uvalue = !Z, name = '!Z')
  880.  
  881.                 ;Annotation base
  882. pw.pwidgets(3)= (a = widget_base(cbase, /column, /FRAME))
  883. junk = widget_base(a, /ROW)
  884. junk1 = row_buttons(junk, '',  ['Arrow', 'Box', 'Text', 'Legend'],$
  885.     "#Cpw.amode="+strtrim(indgen(4),2), /EXCLUSIVE, SET_BUTT=0)
  886. junk1 = widget_button(junk, value='Undo', /NO_REL, uvalue = 'UNDO')
  887.  
  888. junk = row_buttons(a, 'Coordinates:', ['Data', 'Relative'], $
  889.     ['#Cpw.acoord=0', '#Cpw.acoord=1'], /EXCLUSIVE, SET_BUTT=0)
  890. junk = row_buttons(a, 'Box background:', ['Transparent','Erase'], $
  891.     ['#Cpw.aback=0', '#Cpw.aback=1'], /EXCLUSIVE, SET_BUTT=0)
  892.  
  893. junk = widget_base(a, /ROW)
  894. junk1 = widget_label(junk, xsize=70, value='Text:')
  895. pw.atext = widget_text(junk, xsize=28, ysize=1, $
  896.         uvalue = '#Ci=0', /FRAME, /EDIT)  ;Do nothing 
  897.  
  898. a_color = CW_COLOR_INDEX(a, label = 'Color ', uvalue = '#Npw.acolor=', NCOLORS=16)
  899.  
  900.  
  901. width = 32
  902. window, /free, /pixmap, xsize = width, ysize=16
  903. b = widget_base(a, /row)    ;THICKNESS
  904. junk = widget_label(b, value='Thickness:', xsize=70)
  905. b = widget_base(b, /row, /exclusive)
  906. for i=1,6 do begin
  907.     erase, 0
  908.     plots, [0,width-1], [8,8], /dev, thick = i, lines=0, col=col
  909.     pw.thick(i) = widget_button(b, value = b_button(tvrd()), $
  910.             uvalue = '#Cpw.athick='+strtrim(i,2), /NO_REL)
  911.     if i eq 1 then widget_control, pw.thick(i), /SET_BUTTON
  912.     endfor
  913. widget_control, pw.thick(1), /SET_BUTTON
  914. wdelete
  915.  
  916. junk = charsize_but(a, 32, '#Cpw.atextsize=', set = 1)
  917.  
  918. junk = row_buttons(a, "Text Alignment:", $
  919.     ['Left', 'Centered', 'Right'], $
  920.     ["#Cpw.atextal = 0", "#Cpw.atextal = .5", "#Cpw.atextal = 1"], $
  921.     /EXCLUSIVE, SET_BUTTON = 0)
  922.  
  923. pw.txt = WIDGET_TEXT(mainl, ysize = 1, xsize = 24, /frame)
  924.  
  925.  
  926. widget_control, pw.main,/real
  927. widget_control, pw.color, set_value = !p.color
  928. widget_control, a_color, set_value = !p.color
  929. widget_control, pw.background, set_value = !p.background
  930. widget_control, pw.draw, get_value = i
  931. pw.window = i
  932. for i=1,n_elements(base_names)-1 do widget_control, pw.pwidgets(i), map=0
  933. pw_redraw
  934.  
  935. if !d.name eq 'X' then begin    ;Tricky for X windows.
  936.     device, translation = i    ;Get the translations
  937.     pw.xor_color = i(0) xor i(!d.n_colors-1)
  938.     i = 0            ;Clean up
  939. endif else pw.xor_color = !d.n_colors-1
  940.  
  941. xmanager, "pwidget", pw.main, EVENT_HANDLER = 'pwidget_events', GROUP = group
  942. if n_elements(save) ne 0 then $
  943.     save = { PW_SAVE_STRUCT, pw: pw, style: style, list: list, $
  944.         x: !X, y: !Y, p: !P}
  945. !x = original.x
  946. !y = original.y
  947. !p = original.p
  948.  
  949.  
  950. end
  951.